<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Transaction tuning</title>
    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
    <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
    <link rel="start" href="index.html" title="Berkeley DB Programmer's Reference Guide" />
    <link rel="up" href="transapp.html" title="Chapter 12.  Berkeley DB Transactional Data Store Applications" />
    <link rel="prev" href="transapp_reclimit.html" title="Berkeley DB recoverability" />
    <link rel="next" href="transapp_throughput.html" title="Transaction throughput" />
  </head>
  <body>
    <div xmlns="" class="navheader">
      <div class="libver">
        <p>Library Version 12.1.6.2</p>
      </div>
      <table width="100%" summary="Navigation header">
        <tr>
          <th colspan="3" align="center">Transaction tuning</th>
        </tr>
        <tr>
          <td width="20%" align="left"><a accesskey="p" href="transapp_reclimit.html">Prev</a> </td>
          <th width="60%" align="center">Chapter 12.  Berkeley DB Transactional Data Store Applications </th>
          <td width="20%" align="right"> <a accesskey="n" href="transapp_throughput.html">Next</a></td>
        </tr>
      </table>
      <hr />
    </div>
    <div class="sect1" lang="en" xml:lang="en">
      <div class="titlepage">
        <div>
          <div>
            <h2 class="title" style="clear: both"><a id="transapp_tune"></a>Transaction tuning</h2>
          </div>
        </div>
      </div>
      <p>
        There are a few different issues to consider when tuning the
        performance of Berkeley DB transactional applications. First,
        you should review <a class="xref" href="am_misc_tune.html" title="Access method tuning">Access method tuning</a>, as the tuning issues for
        access method applications are applicable to transactional
        applications as well. The following are additional tuning
        issues for Berkeley DB transactional applications:
    </p>
      <div class="variablelist">
        <dl>
          <dt>
            <span class="term">access method</span>
          </dt>
          <dd>
                Highly concurrent applications should use the
                Queue access method, where possible, as it provides
                finer-granularity of locking than the other access
                methods. Otherwise, applications usually see better
                concurrency when using the Btree access method than
                when using either the Hash or Recno access
                methods.
            </dd>
          <dt>
            <span class="term">record numbers</span>
          </dt>
          <dd>
                Using record numbers outside of the Queue access
                method will often slow down concurrent applications as
                they limit the degree of concurrency available in the
                database. Using the Recno access method, or the Btree
                access method with retrieval by record number
                configured can slow applications down.
            </dd>
          <dt>
            <span class="term">Btree database size</span>
          </dt>
          <dd>
                When using the Btree access method, applications
                supporting concurrent access may see excessive numbers
                of deadlocks in small databases. There are two
                different approaches to resolving this problem. First,
                as the Btree access method uses page-level locking,
                decreasing the database page size can result in fewer
                lock conflicts. Second, in the case of databases that
                are cyclically growing and shrinking, turning off
                reverse splits (with <a href="../api_reference/C/dbset_flags.html#dbset_flags_DB_REVSPLITOFF" class="olink">DB_REVSPLITOFF</a>) can leave the
                database with enough pages that there will be fewer
                lock conflicts.
            </dd>
          <dt>
            <span class="term">read locks</span>
          </dt>
          <dd>
                Performing all read operations outside of
                transactions or at <a class="xref" href="transapp_read.html" title="Degrees of isolation">Degrees of isolation</a> can often
                significantly increase application throughput. In
                addition, limiting the lifetime of non-transactional
                cursors will reduce the length of times locks are
                held, thereby improving concurrency.
            </dd>
          <dt>
            <span class="term"><a href="../api_reference/C/envset_flags.html#set_flags_DB_DIRECT_DB" class="olink">DB_DIRECT_DB</a>, <a href="../api_reference/C/envlog_set_config.html#log_set_config_DB_LOG_DIRECT" class="olink">DB_LOG_DIRECT</a></span>
          </dt>
          <dd>
                On some systems, avoiding caching in the
                operating system can improve write throughput and
                allow the creation of larger Berkeley DB
                caches.
            </dd>
          <dt>
            <span class="term"><a href="../api_reference/C/dbopen.html#dbopen_DB_READ_UNCOMMITTED" class="olink">DB_READ_UNCOMMITTED</a>, <a href="../api_reference/C/dbcget.html#dbcget_DB_READ_COMMITTED" class="olink">DB_READ_COMMITTED</a></span>
          </dt>
          <dd>
            <p>
                    Consider decreasing the level of isolation of
                    transaction using the <a href="../api_reference/C/dbopen.html#dbopen_DB_READ_UNCOMMITTED" class="olink">DB_READ_UNCOMMITTED</a>, or
                    <a href="../api_reference/C/dbcget.html#dbcget_DB_READ_COMMITTED" class="olink">DB_READ_COMMITTED</a> flags for transactions or
                    cursors or the <a href="../api_reference/C/dbopen.html#dbopen_DB_READ_UNCOMMITTED" class="olink">DB_READ_UNCOMMITTED</a> flag on
                    individual read operations. The
                    <a href="../api_reference/C/dbcget.html#dbcget_DB_READ_COMMITTED" class="olink">DB_READ_COMMITTED</a> flag will release read locks
                    on cursors as soon as the data page is nolonger
                    referenced. This is also called <span class="emphasis"><em> degree
                    2 isolation</em></span>. This will tend to
                    block write operations for shorter periods for
                    applications that do not need to have repeatable
                    reads for cursor operations. 
                </p>
            <p> 
                    The <a href="../api_reference/C/dbopen.html#dbopen_DB_READ_UNCOMMITTED" class="olink">DB_READ_UNCOMMITTED</a> flag will allow read
                    operations to potentially return data which has
                    been modified but not yet committed, and can
                    significantly increase application throughput in
                    applications that do not require data be
                    guaranteed to be permanent in the database. This
                    is also called <span class="emphasis"><em>degree 1
                    isolation</em></span>, or <span class="emphasis"><em>dirty
                    reads</em></span>. 
                </p>
          </dd>
          <dt>
            <span class="term">
              <a href="../api_reference/C/dbcget.html#dbcget_DB_RMW" class="olink">DB_RMW</a>
            </span>
          </dt>
          <dd> 
                If there are many deadlocks, consider using the
                <a href="../api_reference/C/dbcget.html#dbcget_DB_RMW" class="olink">DB_RMW</a> flag to immediately acquire write locks when
                reading data items that will subsequently be modified.
                Although this flag may increase contention (because
                write locks are held longer than they would otherwise
                be), it may decrease the number of deadlocks that
                occur.
            </dd>
          <dt>
            <span class="term"><a href="../api_reference/C/envset_flags.html#set_flags_DB_TXN_WRITE_NOSYNC" class="olink">DB_TXN_WRITE_NOSYNC</a>, <a href="../api_reference/C/envset_flags.html#envset_flags_DB_TXN_NOSYNC" class="olink">DB_TXN_NOSYNC</a></span>
          </dt>
          <dd>
                By default, transactional commit in Berkeley DB
                implies durability, that is, all committed operations
                will be present in the database after recovery from
                any application or system failure. For applications
                not requiring that level of certainty, specifying the
                <a href="../api_reference/C/envset_flags.html#envset_flags_DB_TXN_NOSYNC" class="olink">DB_TXN_NOSYNC</a> flag will often provide a significant
                performance improvement. In this case, the database
                will still be fully recoverable, but some number of
                committed transactions might be lost after application
                or system failure.
            </dd>
          <dt>
            <span class="term">access databases in order</span>
          </dt>
          <dd>
                When modifying multiple databases in a single
                transaction, always access physical files and
                databases within physical files, in the same order
                where possible. In addition, avoid returning to a
                physical file or database, that is, avoid accessing a
                database, moving on to another database and then
                returning to the first database. This can
                significantly reduce the chance of deadlock between
                threads of control.
            </dd>
          <dt>
            <span class="term">large key/data items</span>
          </dt>
          <dd>
                Transactional protections in Berkeley DB are
                guaranteed by before and after physical image logging.
                This means applications modifying large key/data items
                also write large log records, and, in the case of the
                default transaction commit, threads of control must
                wait until those log records have been flushed to
                disk. Applications supporting concurrent access should
                try and keep key/data items small wherever
                possible.
            </dd>
          <dt>
            <span class="term">mutex selection</span>
          </dt>
          <dd>
            <p>
                    During configuration, Berkeley DB selects a
                    mutex implementation for the architecture.
                    Berkeley DB normally prefers blocking-mutex
                    implementations over non-blocking ones. For
                    example, Berkeley DB will select POSIX pthread
                    mutex interfaces rather than assembly-code
                    test-and-set spin mutexes because pthread mutexes
                    are usually more efficient and less likely to
                    waste CPU cycles spinning without getting any work
                    accomplished.
                </p>
            <p>
                    For some applications and systems (generally
                    highly concurrent applications on large
                    multiprocessor systems), Berkeley DB makes the
                    wrong choice. In some cases, better performance
                    can be achieved by configuring with the
                    <a href="../installation/build_unix_conf.html#build_unix_conf.--with-mutex" class="olink">--with-mutex</a> argument and selecting a different
                    mutex implementation than the one selected by
                    Berkeley DB. When a test-and-set spin mutex
                    implementation is selected, it may be useful to
                    tune the number of spins made before yielding the
                    processor and sleeping. This may be particularly
                    beneficial for systems containing several
                    hyperthreaded processor cores. For more
                    information, see the <a href="../api_reference/C/mutexset_tas_spins.html" class="olink">DB_ENV-&gt;mutex_set_tas_spins()</a> method.
                </p>
            <p> 
                    Finally, Berkeley DB may put multiple mutexes
                    on individual cache lines. When tuning Berkeley DB
                    for large multiprocessor systems, it may be useful
                    to tune mutex alignment using the <a href="../api_reference/C/mutexset_align.html" class="olink">DB_ENV-&gt;mutex_set_align()</a>
                    method. 
                </p>
          </dd>
          <dt>
            <span class="term">
              <a href="../installation/build_unix_conf.html#build_unix_conf.--enable-posixmutexes" class="olink">--enable-posix-mutexes</a>
            </span>
          </dt>
          <dd>
                By default, the Berkeley DB library will only
                select the POSIX pthread mutex implementation if it
                supports mutexes shared between multiple processes. If
                your application does not share its database
                environment between processes and your system's POSIX
                mutex support was not selected because it did not
                support inter-process mutexes, you may be able to
                increase performance and transactional throughput by
                configuring with the <a href="../installation/build_unix_conf.html#build_unix_conf.--enable-posixmutexes" class="olink">--enable-posix-mutexes</a>
                argument.
            </dd>
          <dt>
            <span class="term">log buffer size</span>
          </dt>
          <dd>
                Berkeley DB internally maintains a buffer of log
                writes. The buffer is written to disk at transaction
                commit, by default, or, whenever it is filled. If it
                is consistently being filled before transaction
                commit, it will be written multiple times per
                transaction, costing application performance. In these
                cases, increasing the size of the log buffer can
                increase application throughput.
            </dd>
          <dt>
            <span class="term">log file location</span>
          </dt>
          <dd>
                If the database environment's log files are on
                the same disk as the databases, the disk arms will
                have to seek back-and-forth between the two. Placing
                the log files and the databases on different disk arms
                can often increase application throughput.
            </dd>
          <dt>
            <span class="term">trickle write</span>
          </dt>
          <dd>
                In some applications, the cache is sufficiently
                active and dirty that readers frequently need to write
                a dirty page in order to have space in which to read a
                new page from the backing database file. You can use
                the <a href="../api_reference/C/db_stat.html" class="olink">db_stat</a> utility (or the statistics returned by the
                <a href="../api_reference/C/mempstat.html" class="olink">DB_ENV-&gt;memp_stat()</a> method) to see how often this is happening
                in your application's cache. In this case, using a
                separate thread of control and the <a href="../api_reference/C/memptrickle.html" class="olink">DB_ENV-&gt;memp_trickle()</a>
                method to trickle-write pages can often increase the
                overall throughput of the application.
            </dd>
        </dl>
      </div>
    </div>
    <div class="navfooter">
      <hr />
      <table width="100%" summary="Navigation footer">
        <tr>
          <td width="40%" align="left"><a accesskey="p" href="transapp_reclimit.html">Prev</a> </td>
          <td width="20%" align="center">
            <a accesskey="u" href="transapp.html">Up</a>
          </td>
          <td width="40%" align="right"> <a accesskey="n" href="transapp_throughput.html">Next</a></td>
        </tr>
        <tr>
          <td width="40%" align="left" valign="top">Berkeley DB recoverability </td>
          <td width="20%" align="center">
            <a accesskey="h" href="index.html">Home</a>
          </td>
          <td width="40%" align="right" valign="top"> Transaction
        throughput</td>
        </tr>
      </table>
    </div>
  </body>
</html>
